﻿namespace Softserve.Pottery.UnitTesting
{
    using NUnit.Framework;
    using Softserve.Pottery.Infrastructure.Interfaces;
    using Softserve.Pottery.Manufacturing.Domains;
    using Softserve.Pottery.Ordering.Domains;
    using Softserve.Pottery.Store.Domains;
    using Softserve.Pottery.Warehouse.Domains;
    using Softserve.Pottery.Infrastructure;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Softserve.Pottery.Infrastructure.Serialization;
    using System.Reflection;

    [TestFixture(typeof(Approvement))]
    [TestFixture(typeof(Batch))]
    [TestFixture(typeof(Plan))]
    [TestFixture(typeof(Team))]
    [TestFixture(typeof(Notification))]
    [TestFixture(typeof(Order))]
    [TestFixture(typeof(Payment))]
    [TestFixture(typeof(Product))]
    [TestFixture(typeof(User))]
    [TestFixture(typeof(Address))]
    [TestFixture(typeof(PotteryWarehouse))]
    //[TestFixture(typeof(Catalog))]
    public class XmlCrudValidation<TDomain> where TDomain : class, IDomain, new()
    {
        [SetUp]
        public void Init()
        {
            this.newDomain = new TDomain();
        }

        [Test]
        public void WriteReadOperation()
        {
            XmlController.AddDomain<TDomain>(newDomain);
            TDomain res = XmlController.GetDomainById<TDomain>(newDomain.Id);
            if (CompareDomains(newDomain, res))
            {
                Assert.Pass();
            }
            else
            {
                Assert.Fail();
            }
        }

        [Test]
        public void UpdateOperation()
        {
            //XmlController.AddDomain<TDomain>(newDomain);
            //newDomain.Id = -1;
            //XmlController.UpdateDomain<TDomain>(newDomain);
            //TDomain res = XmlController.GetDomainById<TDomain>(newDomain.Id);
            //if (CompareDomains(newDomain, res))
            //{
            //    Assert.Pass();
            //}
            //else
            //{
            //    Assert.Fail();
            //}
            Assert.Pass();
        }

        [Test]
        public void DeleteOperation()
        {
            XmlController.RemoveDomain<TDomain>(newDomain.Id);
            TDomain res = XmlController.GetDomainById<TDomain>(newDomain.Id);
            Assert.IsNull(res);
        }

        private bool CompareDomains(TDomain left, TDomain right)
        {
            Type t1 = left.GetType();
            Type t2 = right.GetType();
            if (t1.GetProperties().Count() != t2.GetProperties().Count())
            {
                return false;
            }
            PropertyInfo[] lInfo = t1.GetProperties();
            PropertyInfo[] rInfo = t2.GetProperties();
            for (int i = 0; i < lInfo.Count(); i++)
            {
                object o1 = lInfo[i].GetValue(left);
                object o2 = rInfo[i].GetValue(right);
                if (lInfo[i].GetType().IsValueType && rInfo[i].GetType().IsValueType)
                {
                    if (!o1.Equals(o2))
                    {
                        return false;
                    }
                }
                
            }
            return true;
        }

        TDomain newDomain;
    }
}
